from typing import Any

from aiogram import F
from aiogram_dialog import Dialog, DialogManager, Window
from aiogram_dialog.widgets.input import TextInput
from aiogram_dialog.widgets.kbd import (
    Back,
    Button,
    Cancel,
    Group,
    ScrollingGroup,
    Select,
    Start,
)
from aiogram_dialog.widgets.text import Const, Format

from src.bot.dialogs.widgets import LocaleText, StartWithData
from src.bot.states import OrderDetailsSG, PaymentSG, PromocodeSG
from src.bot.states.user import BuyAccountSG

from ...getters.categories import categories_getter
from ...getters.countries import countries_getter
from ...getters.orders import order_summary_getter
from ...getters.product import available_products_getter
from .handlers import create_order, set_amount, set_category_id, set_country_id


async def on_process_result(_, result: Any, manager: DialogManager):
    """Добавляем результат вложенного диалога в текущий"""

    ctx = manager.current_context()
    if result and isinstance(result, dict):
        ctx.dialog_data.update(result)


select_contry_window = Window(
    LocaleText("select-country-msg"),
    ScrollingGroup(
        Select(
            Format("{item.name}"),
            "countries_sel",
            lambda country: country.id,
            "countries",
            on_click=set_country_id,
        ),
        width=3,
        height=4,
        id="countriessel",
        hide_on_single_page=True,
    ),
    Cancel(LocaleText("back-btn")),
    state=BuyAccountSG.select_country,
    getter=countries_getter,
)


select_category_window = Window(
    LocaleText("select-category-msg"),
    ScrollingGroup(
        Select(
            Format("{item.name}"),
            "categories_sel",
            lambda category: category.id,
            "categories",
            on_click=set_category_id,
        ),
        width=3,
        height=4,
        id="categoriesssel",
        hide_on_single_page=True,
    ),
    Back(LocaleText("back-btn")),
    state=BuyAccountSG.select_category,
    getter=categories_getter,
)

select_amount_window = Window(
    LocaleText(
        "select-amount-msg",
        available_count="{products_count}",
        when=F["products_count"] > 0,
    ),
    LocaleText("no-products-available-msg", when=F["products_count"] == 0),
    TextInput("amount", int, on_success=set_amount),
    Group(
        Button(Const("1"), id="1", on_click=set_amount),
        Button(Const("3"), id="3", on_click=set_amount),
        Button(Const("5"), id="5", on_click=set_amount),
        width=3,
        when=F["products_count"] > 0,
    ),
    Back(LocaleText("back-btn")),
    state=BuyAccountSG.select_amount,
    getter=available_products_getter,
)

overview_order_window = Window(
    LocaleText("order-overview"),
    LocaleText("selected-amount", selected_amount="{dialog_data[selected_amount]}"),
    LocaleText("order-summ", order_summ="{order_summ}"),
    LocaleText(
        "discount-summ", discount_summ="{discount_summ}", when=F["discount_summ"]
    ),
    StartWithData(
        LocaleText("add-balance-btn"),
        id="add_balance_btn",
        state=PaymentSG.select_method,
        data_keys=["order_summ"],
    ),
    StartWithData(
        LocaleText("enter-promocode-btn"),
        id="enter_promocode_btn",
        state=PromocodeSG.enter_promocode,
        data_keys=["order_summ"],
    ),
    Button(
        LocaleText("confirm-btn"),
        id="confirm_order_button",
        on_click=create_order,
    ),
    Back(LocaleText("back-btn")),
    state=BuyAccountSG.overview_order,
    getter=order_summary_getter,
)

order_created_window = Window(
    LocaleText(
        "order-created-msg",
    ),
    StartWithData(
        LocaleText("go-to-order-btn"),
        id="go_to_order_btn",
        state=OrderDetailsSG.order_details,
        data_keys=["order_id"],
    ),
    Cancel(LocaleText("main-menu-btn")),
    state=BuyAccountSG.order_created,
)

create_order_dialog = Dialog(
    select_contry_window,
    select_category_window,
    select_amount_window,
    overview_order_window,
    order_created_window,
    on_process_result=on_process_result,
)
